2.4 RunMainIsolate
这是函数定义。它接收脚本名称、包配置覆盖、是否强制禁用健全的空安全,以及 Dart 选项。
void RunMainIsolate(const char* script_name,
const char* package_config_override,
bool force_no_sound_null_safety,
CommandLineOptions* dart_options) {
如果提供了脚本名称,这段代码提取基本名称(不包含路径),然后设置进程名称为 "dart:[脚本基本名称]
"。
if (script_name != nullptr) {
const char* base_name = strrchr(script_name, '/');
if (base_name == nullptr) {
base_name = script_name;
} else {
base_name++; // Skip '/'.
}
const intptr_t kMaxNameLength = 64;
char name[kMaxNameLength];
Utils::SNPrint(name, kMaxNameLength, "dart:%s", base_name);
Platform::SetProcessName(name);
}
初始化一些变量,包括错误指针、退出代码和隔离标志。
// Call CreateIsolateGroupAndSetup which creates an isolate and loads up
// the specified application script.
char* error = nullptr;
int exit_code = 0;
Dart_IsolateFlags flags;
Dart_IsolateFlagsInitialize(&flags);
根据选项设置是否将主隔离标记为系统隔离。
flags.is_system_isolate = Options::mark_main_isolate_as_system_isolate();
设置快照是否可以安全地使用 madvise(MADV_DONTNEED)
。这在不同的操作系统和调试模式下有不同的行为。
bool dontneed_safe = true;
#if defined(DART_HOST_OS_LINUX)
// This would also be true in Linux, except that Google3 overrides the default
// ELF interpreter to one that apparently doesn't create proper mappings.
dontneed_safe = false;
#elif defined(DEBUG)
// If the snapshot isn't file-backed, madvise(DONT_NEED) is destructive.
if force_load_elf_from_memory() {
dontneed_safe = false;
}
#endif
flags.snapshot_is_dontneed_safe = dontneed_safe;
创建主隔离组并进行设置。这是运行 Dart 代码的关键步骤。
Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
/* is_main_isolate */ true, script_name, "main",
Options::packages_file() == nullptr ? package_config_override
: Options::packages_file(),
&flags, nullptr /* callback_data */, &error, &exit_code,
force_no_sound_null_safety);
如果隔离创建失败,打印错误,清理资源,并退出程序。
if (isolate == nullptr) {
Syslog::PrintErr("%s\n", error);
free(error);
error = nullptr;
Process::TerminateExitCodeHandler();
error = Dart_Cleanup();
if (error != nullptr) {
Syslog::PrintErr("VM cleanup failed: %s\n", error);
free(error);
}
dart::embedder::Cleanup();
Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
}
设置全局变量 main_isolate。
main_isolate = isolate;
进入创建的隔离,并进行一些断言检查。
Dart_EnterIsolate(isolate);
ASSERT(isolate == Dart_CurrentIsolate());
ASSERT(isolate != nullptr);
Dart_Handle result;
进入一个新的 Dart 作用域。
Dart_EnterScope();
断言确保不是在生成内核快照。
// Kernel snapshots should have been handled before reaching this point.
ASSERTgen_snapshot_kind() != kKernel;
获取根库的句柄。
// Lookup the library of the root script.
Dart_Handle root_lib = Dart_RootLibrary();
如果不是预编译运行时且设置了编译所有选项,则编译所有代码。
#if !defined(DART_PRECOMPILED_RUNTIME)
if compile_all() {
result = Dart_CompileAll();
CHECK_RESULT(result);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
如果找不到根库,报错并退出。
if (Dart_IsNull(root_lib)) {
ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
script_name);
}
获取 main 函数的闭包,并检查是否成功。
// Create a closure for the main entry point which is in the exported
// namespace of the root library or invoke a getter of the same name
// in the exported namespace and return the resulting closure.
Dart_Handle main_closure =
Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
CHECK_RESULT(main_closure);
if (!Dart_IsClosure(main_closure)) {
ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
script_name);
}
准备传递给 _startMainIsolate
的参数。
// Call _startIsolate in the isolate library to enable dispatching the
// initial startup message.
const intptr_t kNumIsolateArgs = 2;
Dart_Handle isolate_args[kNumIsolateArgs];
isolate_args[0] = main_closure; // entryPoint
isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
查找 dart:isolate 库并调用 _startMainIsolate
函数来启动主隔离。
Dart_Handle isolate_lib =
Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
result =
Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startMainIsolate"),
kNumIsolateArgs, isolate_args);
CHECK_RESULT(result);
运行 Dart 事件循环,直到最后一个活跃的接收端口关闭。
// Keep handling messages until the last active receive port is closed.
result = Dart_RunLoop();
如果需要生成 JIT 快照且没有编译错误,则生成快照。
// Generate an app snapshot after execution if specified.
if gen_snapshot_kind() == kAppJIT {
if (!Dart_IsCompilationError(result)) {
Snapshot::GenerateAppJITsnapshot_filename();
}
}
CHECK_RESULT(result);
写入依赖文件(如果需要)。
WriteDepsFile();
退出之前进入的 Dart 作用域。
Dart_ExitScope();
关闭隔离。
// Shutdown the isolate.
Dart_ShutdownIsolate();
}
本文作者:Maeiee
本文链接:2.4 RunMainIsolate
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!